// To-do: remove debugging
#include <stdio.h>
/**
 * AppleIIGo
 * W65C02S class
 * (C) 2008 by Marc S. Ressl (mressl@umich.edu)
 * Released under the GPL
 */

#include "W65C02S.h"

W65C02S::W65C02S(Motherboard * motherboard) : CPU(motherboard, "W65C02S") {
	cycleExcess = 0;
}

void W65C02S::onDevicesConnected() {
	CPU::onDevicesConnected();
	iou = motherboard->getIou();
}

void W65C02S::executeInstructions() {
	if (isStop)
		return;
	
	if (isReset) {
		isReset = false;

		if (isRestart) {
			A = X = Y = 0;
			S = 0xff;
			setP(0);
			PC = 0;
		} else
			setP(FLAG6502_B | FLAG6502_I);

		fastCondSetC(getC());
		fastCondSetNZ(getN(), getZ());
		setB(true);
		setD(false);
		setI(true);
		PC = readWord16(0xfffc);
		cycleIndex += 7;
	}
	
	if (isNmi) {
		isNmi = false;
		pushPc();
		push(getP());
		PC = readWord16(0xfffa);
		cycleIndex += 7;
	}
	
	checkIrq();
	
	if (isWait)
		return;

/*	UINT8 A = this->A;
	UINT8 X = this->X;
	UINT8 Y = this->Y;
	UINT8 S = this->S;
	UINT8 P = this->P;
	UINT16 PC = this->PC;*/

	for (cycleIndex = cycleExcess; cycleIndex < cycleNum; ) {
		UINT16 address;
		UINT8 opcode = readByte16(PC);
		
		// To-Do: Remove debugging
		static int isDebugging = 0;
//		if ((isDebugging == 1) && (PC == 0xe4f2))
//			isDebugging = 2;
		if (isDebugging == 2)
			printf("%04x: A:%02x X:%02x Y:%02x op: %02x %02x %02x\n", PC, A, X, Y,
			   readByte16(PC), readByte16(PC+1), readByte16(PC+2));		
		// To-Do: End debugging

		PC++;

		switch(opcode) {
		/*
		 * xxxxxx01 instructions
		 */
		case 0x01:	// ORA (zp,X)
			opOra(readByte16(eazpxind())); cycleIndex += 6; break;
		case 0x05:	// ORA zp
			opOra(readByte8(eazp())); cycleIndex += 3; break;
		case 0x09:	// ORA #imm
			opOra(eaimm()); cycleIndex += 2; break;
		case 0x0d:	// ORA abs
			opOra(readByte16(eaabs())); cycleIndex += 4; break;
		case 0x11:	// ORA (zp),Y
			opOra(readByte16(eazpindyWithPageCrossing())); cycleIndex += 5; break;
		case 0x15:	// ORA zp,X
			opOra(readByte8(eazpx())); cycleIndex += 4; break;
		case 0x19:	// ORA abs,Y
			opOra(readByte16(eaabsyWithPageCrossing())); cycleIndex += 4; break;
		case 0x1d:	// ORA abs,X
			opOra(readByte16(eaabsxWithPageCrossing())); cycleIndex += 4; break;
		case 0x21:	// AND (zp,X)
			opAnd(readByte16(eazpxind())); cycleIndex += 6; break;
		case 0x25:	// AND zp
			opAnd(readByte8(eazp())); cycleIndex += 3; break;
		case 0x29:	// AND #imm
			opAnd(eaimm()); cycleIndex += 2; break;
		case 0x2d:	// AND abs
			opAnd(readByte16(eaabs())); cycleIndex += 4; break;
		case 0x31:	// AND (zp),Y
			opAnd(readByte16(eazpindyWithPageCrossing())); cycleIndex += 5; break;
		case 0x35:	// AND zp,X
			opAnd(readByte8(eazpx())); cycleIndex += 4; break;
		case 0x39:	// AND abs,Y
			opAnd(readByte16(eaabsyWithPageCrossing())); cycleIndex += 4; break;
		case 0x3d:	// AND abs,X
			opAnd(readByte16(eaabsxWithPageCrossing())); cycleIndex += 4; break;
		case 0x41:	// EOR (zp,X)
			opEor(readByte16(eazpxind())); cycleIndex += 6; break;
		case 0x45:	// EOR zp
			opEor(readByte8(eazp())); cycleIndex += 3; break;
		case 0x49:	// EOR #imm
			opEor(eaimm()); cycleIndex += 2; break;
		case 0x4d:	// EOR abs
			opEor(readByte16(eaabs())); cycleIndex += 4; break;
		case 0x51:	// EOR (zp),Y
			opEor(readByte16(eazpindyWithPageCrossing())); cycleIndex += 5; break;
		case 0x55:	// EOR zp,X
			opEor(readByte8(eazpx())); cycleIndex += 4; break;
		case 0x59:	// EOR abs,Y
			opEor(readByte16(eaabsyWithPageCrossing())); cycleIndex += 4; break;
		case 0x5d:	// EOR abs,X
			opEor(readByte16(eaabsxWithPageCrossing())); cycleIndex += 4; break;
		case 0x61:	// ADC (zp,X)
			opAdc(readByte16(eazpxind())); cycleIndex += 6; break;
		case 0x65:	// ADC zp
			opAdc(readByte8(eazp())); cycleIndex += 3; break;
		case 0x69:	// ADC #imm
			opAdc(eaimm()); cycleIndex += 2; break;
		case 0x6d:	// ADC abs
			opAdc(readByte16(eaabs())); cycleIndex += 4; break;
		case 0x71:	// ADC (zp),Y
			opAdc(readByte16(eazpindyWithPageCrossing())); cycleIndex += 5; break;
		case 0x75:	// ADC zp,X
			opAdc(readByte8(eazpx())); cycleIndex += 4; break;
		case 0x79:	// ADC abs,Y
			opAdc(readByte16(eaabsyWithPageCrossing())); cycleIndex += 4; break;
		case 0x7d:	// ADC abs,X
			opAdc(readByte16(eaabsxWithPageCrossing())); cycleIndex += 4; break;
		case 0x81:	// STA (zp,X)
			writeByte16(eazpxind(), A); cycleIndex += 6; break;
		case 0x85:	// STA zp
			writeByte8(eazp(), A); cycleIndex += 3; break;
		case 0x8d:	// STA abs
			writeByte16(eaabs(), A); cycleIndex += 4; break;
		case 0x91:	// STA (zp),Y
			writeByte16(eazpindy(), A); cycleIndex += 6; break;
		case 0x95:	// STA zp,X
			writeByte8(eazpx(), A); cycleIndex += 4; break;
		case 0x99:	// STA abs,Y
			writeByte16(eaabsy(), A); cycleIndex += 5; break;
		case 0x9d:	// STA abs,X
			writeByte16(eaabsx(), A); cycleIndex += 5; break;
		case 0xa1:	// LDA (zp,X)
			opLda(readByte16(eazpxind())); cycleIndex += 6; break;
		case 0xa5:	// LDA zp
			opLda(readByte8(eazp())); cycleIndex += 3; break;
		case 0xa9:	// LDA #imm
			opLda(eaimm()); cycleIndex += 2; break;
		case 0xad:	// LDA abs
			opLda(readByte16(eaabs())); cycleIndex += 4; break;
		case 0xb1:	// LDA (zp),Y
			opLda(readByte16(eazpindyWithPageCrossing())); cycleIndex += 5; break;
		case 0xb5:	// LDA zp,X
			opLda(readByte8(eazpx())); cycleIndex += 4; break;
		case 0xb9:	// LDA abs,Y
			opLda(readByte16(eaabsyWithPageCrossing())); cycleIndex += 4; break;
		case 0xbd:	// LDA abs,X
			opLda(readByte16(eaabsxWithPageCrossing())); cycleIndex += 4; break;
		case 0xc1:	// CMP (zp,X)
			opCmp(readByte16(eazpxind())); cycleIndex += 6; break;
		case 0xc5:	// CMP zp
			opCmp(readByte8(eazp())); cycleIndex += 3; break;
		case 0xc9:	// CMP #imm
			opCmp(eaimm()); cycleIndex += 2; break;
		case 0xcd:	// CMP abs
			opCmp(readByte16(eaabs())); cycleIndex += 4; break;
		case 0xd1:	// CMP (zp),Y
			opCmp(readByte16(eazpindyWithPageCrossing())); cycleIndex += 5; break;
		case 0xd5:	// CMP zp,X
			opCmp(readByte8(eazpx())); cycleIndex += 4; break;
		case 0xd9:	// CMP abs,Y
			opCmp(readByte16(eaabsyWithPageCrossing())); cycleIndex += 4; break;
		case 0xdd:	// CMP abs,X
			opCmp(readByte16(eaabsxWithPageCrossing())); cycleIndex += 4; break;
		case 0xe1:	// SBC (zp,X)
			opSbc(readByte16(eazpxind())); cycleIndex += 6; break;
		case 0xe5:	// SBC zp
			opSbc(readByte8(eazp())); cycleIndex += 3; break;
		case 0xe9:	// SBC #imm
			opSbc(eaimm()); cycleIndex += 2; break;
		case 0xed:	// SBC abs
			opSbc(readByte16(eaabs())); cycleIndex += 4; break;
		case 0xf1:	// SBC (zp),Y
			opSbc(readByte16(eazpindyWithPageCrossing())); cycleIndex += 5; break;
		case 0xf5:	// SBC zp,X
			opSbc(readByte8(eazpx())); cycleIndex += 4; break;
		case 0xf9:	// SBC abs,Y
			opSbc(readByte16(eaabsyWithPageCrossing())); cycleIndex += 4; break;
		case 0xfd:	// SBC abs,X
			opSbc(readByte16(eaabsxWithPageCrossing())); cycleIndex += 4; break;

		/*
		 * xxxxxx10 instructions
		 */
		case 0x06:	// ASL zp
			address = eazp();
			writeByte8(address, opAsl(readByte8(address))); cycleIndex += 5; break;
		case 0x0a:	// ASL A
			A = opAsl(A); cycleIndex += 2; break;
		case 0x0e:	// ASL abs
			address = eaabs();
			writeByte16(address, opAsl(readByte16(address))); cycleIndex += 6; break;
		case 0x16:	// ASL zp,X
			address = eazpx();
			writeByte8(address, opAsl(readByte8(address))); cycleIndex += 6; break;
		case 0x1e:	// ASL abs,X
			address = eaabsxWithPageCrossing();
			writeByte16(address, opAsl(readByte16(address))); cycleIndex += 6; break;
		case 0x26:	// ROL zp
			address = eazp();
			writeByte8(address, opRol(readByte8(address))); cycleIndex += 5; break;
		case 0x2a:	// ROL A
			A = opRol(A); cycleIndex += 2; break;
		case 0x2e:	// ROL abs
			address = eaabs();
			writeByte16(address, opRol(readByte16(address))); cycleIndex += 6; break;
		case 0x36:	// ROL zp,X
			address = eazpx();
			writeByte8(address, opRol(readByte8(address))); cycleIndex += 6; break;
		case 0x3e:	// ROL abs,X
			address = eaabsx();
			writeByte16(address, opRol(readByte16(address))); cycleIndex += 6; break;
		case 0x46:	// LSR zp
			address = eazp();
			writeByte8(address, opLsr(readByte8(address))); cycleIndex += 5; break;
		case 0x4a:	// LSR A
			A = opLsr(A); cycleIndex += 2; break;
		case 0x4e:	// LSR abs
			address = eaabs();
			writeByte16(address, opLsr(readByte16(address))); cycleIndex += 6; break;
		case 0x56:	// LSR zp,X
			address = eazpx();
			writeByte8(address, opLsr(readByte8(address))); cycleIndex += 6; break;
		case 0x5e:	// LSR abs,X
			address = eaabsx();
			writeByte16(address, opLsr(readByte16(address))); cycleIndex += 6; break;
		case 0x66:	// ROR zp
			address = eazp();
			writeByte8(address, opRor(readByte8(address))); cycleIndex += 5; break;
		case 0x6a:	// ROR A
			A = opRor(A); cycleIndex += 2; break;
		case 0x6e:	// ROR abs
			address = eaabs();
			writeByte16(address, opRor(readByte16(address))); cycleIndex += 6; break;
		case 0x76:	// ROR zp,X
			address = eazpx();
			writeByte8(address, opRor(readByte8(address))); cycleIndex += 6; break;
		case 0x7e:	// ROR abs,X
			address = eaabsx();
			writeByte16(address, opRor(readByte16(address))); cycleIndex += 6; break;
		case 0x86:	// STX zp
			writeByte8(eazp(), X); cycleIndex += 3; break;
		case 0x8e:	// STX abs
			writeByte16(eaabs(), X); cycleIndex += 4; break;
		case 0x96:	// STX zp,Y
			writeByte8(eazpy(), X); cycleIndex += 4; break;
		case 0xa2:	// LDX #imm		
			opLdx(eaimm()); cycleIndex += 2; break;
		case 0xa6:	// LDX zp
			opLdx(readByte8(eazp())); cycleIndex += 3; break;
		case 0xae:	// LDX abs
			opLdx(readByte16(eaabs())); cycleIndex += 4; break;
		case 0xbe:	// LDX abs,Y
			opLdx(readByte16(eaabsyWithPageCrossing())); cycleIndex += 4; break;
		case 0xb6:	// LDX zp,Y
			opLdx(readByte8(eazpy())); cycleIndex += 4; break;
		case 0xc6:	// DEC zp
			address = eazp();
			writeByte8(address, opDec(readByte8(address))); cycleIndex += 5; break;
		case 0xce:	// DEC abs
			address = eaabs();
			writeByte16(address, opDec(readByte16(address))); cycleIndex += 6; break;
		case 0xd6:	// DEC zp,X
			address = eazpx();
			writeByte8(address, opDec(readByte8(address))); cycleIndex += 6; break;
		case 0xde:	// DEC abs,X
			address = eaabsx();
			writeByte16(address, opDec(readByte16(address))); cycleIndex += 6; break;
		case 0xe6:	// INC zp
			address = eazp();
			writeByte8(address, opInc(readByte8(address))); cycleIndex += 5; break;
		case 0xee:	// INC abs
			address = eaabs();
			writeByte16(address, opInc(readByte16(address))); cycleIndex += 6; break;
		case 0xf6:	// INC zp,X
			address = eazpx();
			writeByte8(address, opInc(readByte8(address))); cycleIndex += 6; break;
		case 0xfe:	// INC abs,X
			address = eaabsx();
			writeByte16(address, opInc(readByte16(address))); cycleIndex += 6; break;

		/*
		 * xxxxxx00 instructions
		 */
		case 0x24:	// BIT zp
			opBit(readByte8(eazp())); cycleIndex += 3; break;
		case 0x2c:	// BIT abs
			opBit(readByte16(eaabs())); cycleIndex += 4; break;
		case 0x4c:	// JMP abs
			PC = eaabs(); cycleIndex += 3; break;
		case 0x6c:	// JMP (abs)
			PC = eaabsindWithPageCrossing(); cycleIndex += 6; break;
		case 0x84:	// STY zp
			writeByte8(eazp(), Y); cycleIndex += 3; break;
		case 0x8c:	// STY abs
			writeByte16(eaabs(), Y); cycleIndex += 4; break;
		case 0x94:	// STY zp,X
			writeByte8(eazpx(), Y); cycleIndex += 4; break;
		case 0xa0:	// LDY #imm
			opLdy(eaimm()); cycleIndex += 2; break;
		case 0xa4:	// LDY zp
			opLdy(readByte8(eazp())); cycleIndex += 3; break;
		case 0xac:	// LDY abs
			opLdy(readByte16(eaabs())); cycleIndex += 4; break;
		case 0xb4:	// LDY zp,X
			opLdy(readByte8(eazpx())); cycleIndex += 4; break;
		case 0xbc:	// LDY abs,X
			opLdy(readByte16(eaabsxWithPageCrossing())); cycleIndex += 4; break;
		case 0xc0:	// CPY #imm
			opCpy(eaimm()); cycleIndex += 2; break;
		case 0xc4:	// CPY zp
			opCpy(readByte8(eazp())); cycleIndex += 3; break;
		case 0xcc:	// CPY abs
			opCpy(readByte16(eaabs())); cycleIndex += 4; break;
		case 0xe0:	// CPX #imm
			opCpx(eaimm()); cycleIndex += 2; break;
		case 0xe4:	// CPX zp
			opCpx(readByte8(eazp())); cycleIndex += 3; break;
		case 0xec:	// CPX abs
			opCpx(readByte16(eaabs())); cycleIndex += 4; break;

		/*
		 * xxx10000 instructions
		 */
		case 0x10:	// BPL rr
			opBranch(earel(), !fastCondIsN()); cycleIndex += 2; break;
		case 0x30:	// BMI rr
			opBranch(earel(), fastCondIsN()); cycleIndex += 2; break;
		case 0x50:	// BVC rr
			opBranch(earel(), !getV()); cycleIndex += 2; break;
		case 0x70:	// BVS rr
			opBranch(earel(), getV()); cycleIndex += 2; break;
		case 0x90:	// BCC rr
			opBranch(earel(), !fastCondIsC()); cycleIndex += 2; break;
		case 0xb0:	// BCS rr
			opBranch(earel(), fastCondIsC()); cycleIndex += 2; break;
		case 0xd0:	// BNE rr
			opBranch(earel(), !fastCondIsZ()); cycleIndex += 2; break;
		case 0xf0:	// BEQ rr
			opBranch(earel(), fastCondIsZ()); cycleIndex += 2; break;
		
		/*
		 * Remaining instructions
		 */
		case 0x00:	// BRK
			PC++; pushPc(); setB(true); push(getP()); setI(true);
			PC = readWord16(0xfffe); cycleIndex += 7; break;
		case 0x20:	// JSR abs
			address = eaabs(); PC--; pushPc(); PC = address; cycleIndex += 6; break;
		case 0x40:	// RTI
			setP(pop()); popPc(); cycleIndex += 6; checkIrq(); break;
		case 0x60:	// RTS
			popPc(); PC++; cycleIndex += 6; break;
		case 0x08:	// PHP
			push(getP()); cycleIndex += 3; break;
		case 0x28:	// PLP
			setP(pop()); cycleIndex += 4; checkIrq(); break;
		case 0x48:	// PHA
			push(A); cycleIndex += 3; break;
		case 0x68:	// PLA
			opLda(pop()); cycleIndex += 4; break;
		case 0x88:	// DEY
			Y = opDec(Y); cycleIndex += 2; break;
		case 0xa8:	// TAY
			opLdy(A); cycleIndex += 2; break;
		case 0xc8:	// INY
			Y = opInc(Y); cycleIndex += 2; break;
		case 0xe8:	// INX
			X = opInc(X); cycleIndex += 2; break;
		case 0x18:	// CLC
			fastCondSetC(false); cycleIndex += 2; break;
		case 0x38:	// SEC
			fastCondSetC(true); cycleIndex += 2; break;
		case 0x58:	// CLI
			setI(false); cycleIndex += 2; checkIrq(); break;
		case 0x78:	// SEI
			setI(true); cycleIndex += 2; break;
		case 0x98:	// TYA
			opLda(Y); cycleIndex += 2; break;
		case 0xb8:	// CLV
			setV(false); cycleIndex += 2; break;
		case 0xd8:	// CLD
			setD(false); cycleIndex += 2; break;
		case 0xf8:	// SED
			setD(true); cycleIndex += 2; break;
		case 0x8a:	// TXA
			opLda(X); cycleIndex += 2; break;
		case 0x9a:	// TXS
			S = X; cycleIndex += 2; break;
		case 0xaa:	// TAX
			opLdx(A); cycleIndex += 2; break;
		case 0xba:	// TSX
			opLdx(S); cycleIndex += 2; break;		
		case 0xca:	// DEX
			X = opDec(X); cycleIndex += 2; break;
		case 0xea:	// NOP
			cycleIndex += 2; break;

		/*
		 * 65C02 xxx10010 instructions
		 */
		case 0x12:	// ORA (zp)
			opOra(readByte16(eazpind())); cycleIndex += 5; break;
		case 0x32:	// AND (zp)
			opAnd(readByte16(eazpind())); cycleIndex += 5; break;
		case 0x52:	// EOR (zp)
			opEor(readByte16(eazpind())); cycleIndex += 5; break;
		case 0x72:	// ADC (zp)
			opAdc(readByte16(eazpind())); cycleIndex += 5; break;
		case 0x92:	// STA (zp)
			writeByte16(eazpind(), A); cycleIndex += 5; break;
		case 0xb2:	// LDA (zp)
			opLda(readByte16(eazpind())); cycleIndex += 5; break;
		case 0xd2:	// CMP (zp)
			opCmp(readByte16(eazpind())); cycleIndex += 5; break;
		case 0xf2:	// SBC (zp)
			opSbc(readByte16(eazpind())); cycleIndex += 5; break;
			
		/*
		 * 65C02 other instructions
		 */
		case 0x7c:	// JMP (abs,X)
			PC = eaabsxindWithPageCrossing(); cycleIndex += 6; break;
		case 0x89:	// BIT #imm
			opBit(eaimm()); cycleIndex += 2; break;
		case 0x34:	// BIT zp,X
			opBit(readByte8(eazpx())); cycleIndex += 4; break;
		case 0x3c:	// BIT abs,X
			opBit(eaabsxWithPageCrossing()); cycleIndex += 4; break;
		case 0x04:	// TSB zp
			address = eazp();
			writeByte8(address, opTsb(readByte8(address))); cycleIndex += 5; break;
		case 0x0c:	// TSB abs
			address = eaabs();
			writeByte16(address, opTsb(readByte16(address))); cycleIndex += 6; break;
		case 0x14:	// TRB zp
			address = eazp();
			writeByte8(address, opTrb(readByte8(address))); cycleIndex += 5; break;
		case 0x1c:	// TRB abs
			address = eaabs();
			writeByte16(address, opTrb(readByte16(address))); cycleIndex += 6; break;
		case 0x64:	// STZ zp
			writeByte8(eazp(), 0); cycleIndex += 3; break;
		case 0x9c:	// STZ abs
			writeByte16(eaabs(), 0); cycleIndex += 4; break;
		case 0x74:	// STZ zp,X
			writeByte8(eazpx(), 0); cycleIndex += 4; break;
		case 0x9e:	// STZ abs,X
			writeByte16(eaabsx(), 0); cycleIndex += 5; break;
		case 0x80:	// BRA rr
			opBranch(earel(), true); cycleIndex += 2; break;
		case 0x1a:	// INC A
			A = opInc(A); cycleIndex += 2; break;
		case 0x3a:	// DEC A
			A = opDec(A); cycleIndex += 2; break;
		case 0x5a:	// PHY
			push(Y); cycleIndex += 3; break;
		case 0x7a:	// PLY
			opLdy(pop()); cycleIndex += 4; break;
		case 0xda:	// PHX
			push(X); cycleIndex += 3; break;
		case 0xfa:	// PLX
			opLdx(pop()); cycleIndex += 4; break;	

		/*
		 * W65C02S extensions
		 */
		case 0x07:	// RMB0
			address = eazp();
			writeByte8(address, readByte8(address) & 0xfe); cycleIndex += 5; break;
		case 0x17:	// RMB1
			address = eazp();
			writeByte8(address, readByte8(address) & 0xfd); cycleIndex += 5; break;
		case 0x27:	// RMB2
			address = eazp();
			writeByte8(address, readByte8(address) & 0xfb); cycleIndex += 5; break;
		case 0x37:	// RMB3
			address = eazp();
			writeByte8(address, readByte8(address) & 0xf7); cycleIndex += 5; break;
		case 0x47:	// RMB4
			address = eazp();
			writeByte8(address, readByte8(address) & 0xef); cycleIndex += 5; break;
		case 0x57:	// RMB5
			address = eazp();
			writeByte8(address, readByte8(address) & 0xdf); cycleIndex += 5; break;
		case 0x67:	// RMB6
			address = eazp();
			writeByte8(address, readByte8(address) & 0xbf); cycleIndex += 5; break;
		case 0x77:	// RMB7
			address = eazp();
			writeByte8(address, readByte8(address) & 0x7f); cycleIndex += 5; break;
		case 0x87:	// SMB0
			address = eazp();
			writeByte8(address, readByte8(address) | 0x01); cycleIndex += 5; break;
		case 0x97:	// SMB1
			address = eazp();
			writeByte8(address, readByte8(address) | 0x02); cycleIndex += 5; break;
		case 0xa7:	// SMB2
			address = eazp();
			writeByte8(address, readByte8(address) | 0x04); cycleIndex += 5; break;
		case 0xb7:	// SMB3
			address = eazp();
			writeByte8(address, readByte8(address) | 0x08); cycleIndex += 5; break;
		case 0xc7:	// SMB4
			address = eazp();
			writeByte8(address, readByte8(address) | 0x10); cycleIndex += 5; break;
		case 0xd7:	// SMB5
			address = eazp();
			writeByte8(address, readByte8(address) | 0x20); cycleIndex += 5; break;
		case 0xe7:	// SMB6
			address = eazp();
			writeByte8(address, readByte8(address) | 0x40); cycleIndex += 5; break;
		case 0xf7:	// SMB7
			address = eazp();
			writeByte8(address, readByte8(address) | 0x80); cycleIndex += 5; break;
		case 0x0f:	// BBR0
			opBranch(earel(), !(A & 0x01)); cycleIndex += 2; break;
		case 0x1f:	// BBR1
			opBranch(earel(), !(A & 0x02)); cycleIndex += 2; break;
		case 0x2f:	// BBR2
			opBranch(earel(), !(A & 0x04)); cycleIndex += 2; break;
		case 0x3f:	// BBR3
			opBranch(earel(), !(A & 0x08)); cycleIndex += 2; break;
		case 0x4f:	// BBR4
			opBranch(earel(), !(A & 0x10)); cycleIndex += 2; break;
		case 0x5f:	// BBR5
			opBranch(earel(), !(A & 0x20)); cycleIndex += 2; break;
		case 0x6f:	// BBR6
			opBranch(earel(), !(A & 0x40)); cycleIndex += 2; break;
		case 0x7f:	// BBR7
			opBranch(earel(), !(A & 0x80)); cycleIndex += 2; break;
		case 0x8f:	// BBS0
			opBranch(earel(), (A & 0x01)); cycleIndex += 2; break;
		case 0x9f:	// BBS1
			opBranch(earel(), (A & 0x02)); cycleIndex += 2; break;
		case 0xaf:	// BBS2
			opBranch(earel(), (A & 0x04)); cycleIndex += 2; break;
		case 0xbf:	// BBS3
			opBranch(earel(), (A & 0x08)); cycleIndex += 2; break;
		case 0xcf:	// BBS4
			opBranch(earel(), (A & 0x10)); cycleIndex += 2; break;
		case 0xdf:	// BBS5
			opBranch(earel(), (A & 0x20)); cycleIndex += 2; break;
		case 0xef:	// BBS6
			opBranch(earel(), (A & 0x40)); cycleIndex += 2; break;
		case 0xff:	// BBS7
			opBranch(earel(), (A & 0x80)); cycleIndex += 2; break;
		case 0xcb:	// WAI
			PC--; isWait = true; cycleIndex += 3;
			break;
		case 0xdb:	// STP
			PC--; isStop = true; cycleIndex += 3;
			isStop = true;
			break;

		/*
		 * Unknown instructions
		 */
		case 0x02: case 0x22: case 0x42: case 0x62:
		case 0x82: case 0xc2: case 0xe2:
			eaimm(); cycleIndex += 2; break;
		case 0x03: case 0x13: case 0x23: case 0x33:
		case 0x43: case 0x53: case 0x63: case 0x73:
		case 0x83: case 0x93: case 0xa3: case 0xb3:
		case 0xc3: case 0xd3: case 0xe3: case 0xf3:
		case 0x0b: case 0x1b: case 0x2b: case 0x3b:
		case 0x4b: case 0x5b: case 0x6b: case 0x7b:
		case 0x8b: case 0x9b: case 0xab: case 0xbb:
		case 0xeb: case 0xfb:
			cycleIndex += 1; break;
		case 0x44:
			eaimm(); cycleIndex += 3; break;
		case 0x54: case 0xd4: case 0xf4:
			eaimm(); cycleIndex += 4; break;
		case 0x5c:
			eaabs(); cycleIndex += 8; break;
		case 0xdc: case 0xfc:
			eaabs(); cycleIndex += 4; break;
		}
	}

	cycleExcess = cycleIndex - cycleNum;
	cycleIndex = cycleNum;
	
/*	this->A = A;
	this->X = X;
	this->Y = Y;
	this->S = S;
	this->P = P;
	this->PC = PC;*/
}
